
#ifndef __GLOBAL_DATA_H
#define __GLOBAL_DATA_H

#ifndef _UXTHEME_H_

// From uxtheme.h:
typedef HANDLE HTHEME;          // handle to a section of theme data for class
#endif // THEMEAPI

typedef HANDLE MYHPAINTBUFFER;  // handle to a buffered paint context

typedef BOOL (__stdcall * SETLAYEATTRIB)(HWND hwnd, COLORREF crKey, BYTE bAlpha, DWORD dwFlags);
typedef BOOL (__stdcall * UPDATELAYEREDWINDOW)(HWND hwnd, HDC hdcDst, POINT *pptDst, SIZE *psize, 
											   HDC hdcSrc, POINT *pptSrc, COLORREF crKey, 
											   BLENDFUNCTION *pblend, DWORD dwFlags);
typedef HRESULT (__stdcall * MY_DRAWTHEMEPARENTBACKGROUND)(HWND hWnd, HDC hdc,const RECT *pRec);


/************************************************************************/
/*                                                                      */
/************************************************************************/

typedef BOOL (__stdcall * ALPHABLEND)(HDC,int,int,int,int,HDC,int,int,int,int,BLENDFUNCTION);

class CMyDrawManager : public CObject
{
public:
	CMyDrawManager(CDC& dc);
	virtual ~CMyDrawManager();

	// Operatioins:
	BOOL DrawShadow (CRect rect,					// Shadow will be draw around this rect
		int nDepth,						// Shadow depth (pixels)
		int iMinBrightness = 100,		// Min. brighttness
		int iMaxBrightness = 50,		// Max. beightness
		CBitmap* pBmpSaveBottom = NULL,	// Bitmap may be saved in 
		CBitmap* pBmpSaveRight = NULL,	// two bitmaps
		COLORREF clrBase =(COLORREF)-1,	// Base color
		BOOL bRightShadow = TRUE);		// Shadow on right side

	BOOL HighlightRect (CRect rect,					// Rectangle to be highlighted
		int nPercentage = -1,		// < 100 - darker, > 100 - lighter, -1 - default light
		COLORREF clrTransparent =	// Don't change this color
		(COLORREF)-1,
		int nTolerance = 0,
		COLORREF clrBlend = (COLORREF)-1);

	void FillGradient (	CRect rect, 
		COLORREF colorStart, COLORREF colorFinish,
		BOOL bHorz = TRUE,
		int nStartFlatPercentage = 0,
		int nEndFlatPercentage = 0);

	void FillGradient2 (CRect rect, COLORREF colorStart, COLORREF colorFinish, 
		int nAngle = 0 /* 0 - 360 */);

	void Fill4ColorsGradient (CRect rect, 
		COLORREF colorStart1, COLORREF colorFinish1, 
		COLORREF colorStart2, COLORREF colorFinish2,
		BOOL bHorz = TRUE,
		int nPercentage = 50);	/* 0 - 100 */

	BOOL GrayRect (	CRect rect,					// Rectangle to be grayed
		int nPercentage = -1,		// < 100 - darker, > 100 - lighter, -1 - default light
		COLORREF clrTransparent =	// Don't change this color
		(COLORREF)-1,
		COLORREF clrDisabled =		// Use this color for desaturation
		(COLORREF)-1);

	void MirrorRect (CRect rect, BOOL bHorz = TRUE);

	BOOL DrawGradientRing (	CRect rect,
		COLORREF colorStart, COLORREF colorFinish,
		COLORREF colorBorder,
		int nAngle /* 0 - 360 */,
		int nWidth,
		COLORREF clrFace = (COLORREF) -1);

	void DrawLine (int x1, int y1, int x2, int y2, COLORREF clrLine);
	void DrawLineA (double x1, double y1, double x2, double y2, COLORREF clrLine);
	void DrawEllipse   (const CRect& rect, COLORREF clrFill, COLORREF clrLine);
	void DrawRect (const CRect& rect, COLORREF clrFill, COLORREF clrLine);

	static void DrawAlpha (CDC* pDstDC, const CRect& rectDst, CDC* pSrcDC, const CRect& rectSrc, BYTE nOpacity = 255);

	void FillAlpha (const CRect& rect, BYTE bValue = 255);
	void DrawRotated (CRect rectDest, CDC& dcSrc, BOOL bClockWise);

	// Helpers:
	static COLORREF PixelAlpha (COLORREF srcPixel, int percent);
	static COLORREF PixelAlpha (COLORREF srcPixel, double percentR, double percentG, double percentB);
	static COLORREF PixelAlpha (COLORREF srcPixel, COLORREF dstPixel, int percent);
	static void SetAlphaPixel (COLORREF* pBits, CRect rect, int x, int y, int percent, int iShadowSize,
		COLORREF clrBase = (COLORREF)-1, BOOL bIsRight = TRUE);
	static void SetPixel (COLORREF* pBits, int cx, int cy, int x, int y, COLORREF color);

	// Conversion between the HSL (Hue, Saturation, and Luminosity) and RGB:
	static double HuetoRGB (double m1, double m2, double h);
	static BYTE HueToRGB (float rm1, float rm2, float rh);
	static COLORREF HLStoRGB_ONE (double H, double L, double S);
	static COLORREF HLStoRGB_TWO (double H, double L, double S);
	static void RGBtoHSL (COLORREF rgb, double *H, double *S, double *L);

	// Conversion between the HSV (Hue/Saturation/Value) and RGB:
	static void RGBtoHSV (COLORREF rgb, double *H, double *S, double *V);
	static COLORREF HSVtoRGB (double H, double S, double V);

	static COLORREF SmartMixColors (COLORREF color1, COLORREF color2,
		double dblLumRatio = 1., int k1 = 1, int k2 = 1);

	static COLORREF MixColors (COLORREF clr1, COLORREF clr2, double dblRatio);

	static HBITMAP CreateBitmap_32 (const CSize& size, void** pBits);
	static HBITMAP CreateBitmap_32 (HBITMAP bitmap, COLORREF clrTransparent = -1);
	static HBITMAP PrepareShadowMask (int nDepth,
		COLORREF clrBase,
		int iMinBrightness = 0, int iMaxBrightness = 100);

protected:
	void _FillGradient (CRect rect, 
		COLORREF colorStart, COLORREF colorFinish,
		BOOL bHorz = TRUE,
		int nStartFlatPercentage = 0,
		int nEndFlatPercentage = 0);

	// Attributes:
protected:
	CDC&	m_dc;
};
/************************************************************************/
/*                                                                      */
/************************************************************************/
typedef struct tagDrawState
{
	HBITMAP hbmMono;
	HBITMAP hbmMonoOld;
	HBITMAP hbmOldGlyphs;
}
CMyDrawState;

/************************************************************************/
/* CMyMemDC                                                             */
/************************************************************************/
class CMyMemDC
{
public:
	static BOOL	m_bUseMemoryDC;

	CMyMemDC(CDC& dc, CWnd* pWnd, BYTE alpha = 0);
	CMyMemDC(CDC& dc, const CRect& rect, BYTE alpha = 0);

	virtual ~CMyMemDC();

	CDC& GetDC ()			{	return m_bMemDC ? m_dcMem : m_dc;	}
	BOOL IsMemDC () const	{	return m_bMemDC;					}
	BOOL IsVistaDC () const	{	return m_hBufferedPaint != NULL;	}

protected:
	CDC&		m_dc;
	BOOL		m_bMemDC;
	HANDLE		m_hBufferedPaint;
	CDC			m_dcMem;
	CBitmap		m_bmp;
	CBitmap*	m_pOldBmp;
	CRect		m_rect;
	BYTE		m_alpha;	// Buffered Paint only!
};

typedef enum _MY_BP_BUFFERFORMAT
{
    MY_BPBF_COMPATIBLEBITMAP,    // Compatible bitmap
    MY_BPBF_DIB,                 // Device-independent bitmap
    MY_BPBF_TOPDOWNDIB,          // Top-down device-independent bitmap
    MY_BPBF_TOPDOWNMONODIB       // Top-down monochrome device-independent bitmap
} MY_BP_BUFFERFORMAT;

#define MY_BP_BUFFERFORMATBPBF_COMPOSITED MY_BP_BUFFERFORMATBPBF_DIB

typedef struct _MY_BP_PAINTPARAMS
{
    DWORD                       cbSize;
    DWORD                       dwFlags; // BPPF_ flags
    const RECT *                prcExclude;
    const BLENDFUNCTION *       pBlendFunction;
} MY_BP_PAINTPARAMS;

typedef MYHPAINTBUFFER (__stdcall * MY_BEGINBUFFEREDPAINT)(	HDC hdcTarget, const RECT* rcTarget, 
															MY_BP_BUFFERFORMAT dwFormat, 
															MY_BP_PAINTPARAMS *pPaintParams,
															HDC *phdc);

typedef HRESULT (__stdcall * MY_BUFFEREDPAINTSETALPHA)(MYHPAINTBUFFER hBufferedPaint, const RECT *prc, BYTE alpha);


typedef HRESULT (__stdcall * MY_ENDBUFFEREDPAINT)(MYHPAINTBUFFER hBufferedPaint, BOOL fUpdateTarget);

typedef struct _MYMARGINS {
    int cxLeftWidth;
    int cxRightWidth;
    int cyTopHeight;
    int cyBottomHeight;
} MYMARGINS;

typedef HRESULT (__stdcall * MY_DWMEXTENDFRAMEINTOCLIENTAREA)(HWND hWnd, const MYMARGINS* pMargins);
typedef HRESULT (__stdcall * MY_DWMDEFWINDOWPROC)(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam, LRESULT *plResult);
typedef HRESULT (__stdcall * MY_DWMISCOMPOSITIONENABLED)(BOOL* pfEnabled);

typedef int (WINAPI *MYDTT_CALLBACK_PROC)
(
    HDC hdc,
    LPWSTR pszText,
    int cchText,
    LPRECT prc,
    UINT dwFlags,
    LPARAM lParam);

typedef struct _MYDTTOPTS {
    DWORD dwSize;
    DWORD dwFlags;
    COLORREF crText;
    COLORREF crBorder;
    COLORREF crShadow;
    int iTextShadowType;
    POINT ptShadowOffset;
    int iBorderSize;
    int iFontPropId;
    int iColorPropId;
    int iStateId;
    BOOL fApplyOverlay;
    int iGlowSize;
    MYDTT_CALLBACK_PROC pfnDrawTextCallback;
    LPARAM lParam;
} MYDTTOPTS;

typedef HRESULT (__stdcall * MY_DRAWTHEMETEXTEX)(HTHEME hTheme, HDC hdc, int iPartId, int iStateId, LPCWSTR pszText, int iCharCount, DWORD dwFlags, LPRECT pRect, const MYDTTOPTS *pOptions);
typedef HRESULT (__stdcall * MY_DRAWTHEMEICON)(HTHEME hTheme, HDC hdc, int iPartId, int iStateId, const RECT *pRect, HIMAGELIST himl, int iImageIndex);

class CMFCToolBarImages;

struct MYGLOBAL_DATA
{
	friend class CMyMemDC;

	BOOL	m_bUseSystemFont;	// Use system font for menu/toolbar/ribbons

	// solid brushes with convenient gray colors and system colors
	HBRUSH hbrBtnHilite, hbrBtnShadow;

	HBRUSH hbrWindow;

	// color values of system colors used for CToolBar
	COLORREF clrBtnFace, clrBtnShadow, clrBtnHilite;
	COLORREF clrBtnText, clrWindowFrame;
	COLORREF clrBtnDkShadow, clrBtnLight;
	COLORREF clrGrayedText;
	COLORREF clrHilite;
	COLORREF clrTextHilite;
	COLORREF clrHotText;
	COLORREF clrHotLinkText;

	COLORREF clrBarWindow;
	COLORREF clrBarFace;
	COLORREF clrBarShadow, clrBarHilite;
	COLORREF clrBarDkShadow, clrBarLight;
	COLORREF clrBarText;

	COLORREF clrWindow;
	COLORREF clrWindowText;

	COLORREF clrCaptionText;

	COLORREF clrMenuText;

	COLORREF clrActiveCaption;
	COLORREF clrInactiveCaption;

	COLORREF clrActiveCaptionGradient;
	COLORREF clrInactiveCaptionGradient;

	COLORREF clrInactiveCaptionText;

	COLORREF clrActiveBorder;
	COLORREF clrInactiveBorder;

	CBrush	brBtnFace;
	CBrush	brHilite;
	CBrush	brLight;
	CBrush	brBlack;
	CBrush	brActiveCaption;
	CBrush	brInactiveCaption;
	CBrush	brWindow;

	CBrush brBarFace;

	CPen	penHilite;
	CPen	penBarFace;
	CPen	penBarShadow;

	// Library cursors:
	HCURSOR	m_hcurStretch;
	HCURSOR	m_hcurStretchVert;
	HCURSOR	m_hcurHand;
	HCURSOR	m_hcurSizeAll;
	HCURSOR	m_hcurMoveTab;
	HCURSOR	m_hcurNoMoveTab;
	HCURSOR	m_hcurSelectRow;

	HCURSOR	GetHandCursor ();

	HICON	m_hiconTool;
	HICON	m_hiconLink;
	HICON	m_hiconColors;

	// Shell icon sizes:
	CSize	m_sizeSmallIcon;

	// Toolbar and menu fonts:
	CFont				fontRegular;
	CFont				fontTooltip;
	CFont				fontBold;
	CFont				fontDefaultGUIBold;
	CFont				fontUnderline;
	CFont				fontDefaultGUIUnderline;
	CFont				fontVert;
	CFont				fontVertCaption;
	CFont				fontSmall;

	CFont				fontMarlett;	// Standard Windows menu symbols
						
	BOOL				bIsWindowsNT4;
	BOOL				bIsWindows9x;
	BOOL				bIsWindowsVista;
	BOOL				bDisableAero;
	int					m_nBitsPerPixel;

	BOOL				bIsRemoteSession;
	BOOL				bIsOSAlphaBlendingSupport;

	int					m_nDragFrameThiknessFloat;
	int					m_nDragFrameThiknessDock;
						
	int					m_nAutoHideToolBarSpacing;
	int					m_nAutoHideToolBarMargin;
						
	int					m_nCoveredMainWndClientAreaPercent;

	int					m_nMaxToolTipWidth;

	BOOL				m_bIsBlackHighContrast;
	BOOL				m_bIsWhiteHighContrast;

	BOOL				m_bUseBuiltIn32BitIcons;
	BOOL				m_bUseVisualManagerInBuiltInDialogs;

	CRect				m_rectVirtual;

	BOOL				m_bMenuAnimation;
	BOOL				m_bMenuFadeEffect;

	int					m_nShellAutohideBars;

	BOOL				m_bIsRTL;

	BOOL				m_bEnableAccessibility;
	BOOL				m_bInSettingsChange;

	BOOL				m_bUnderlineKeyboardShortcuts;
	BOOL				m_bSysUnderlineKeyboardShortcuts;
						
// Implementation
	MYGLOBAL_DATA();
	~MYGLOBAL_DATA();

	void UpdateSysColors();
	void UpdateFonts();
	void OnSettingChange ();

	BOOL SetMenuFont (LPLOGFONT lpLogFont, BOOL bHorz);

	int GetTextHeight (BOOL bHorz = TRUE)
	{
		return bHorz ? m_nTextHeightHorz : m_nTextHeightVert;
	}

	int GetTextWidth (BOOL bHorz = TRUE)
	{
		return bHorz ? m_nTextWidthHorz : m_nTextWidthVert;
	}

	int GetTextMargins (BOOL bHorz = TRUE)
	{
		return bHorz ? m_nTextMarginsHorz : m_nTextMarginsVert;
	}

	double GetRibbonImageScale ()
	{
		return m_bIsRibbonImageScale ? m_dblRibbonImageScale : 1.;
	}

	void EnableRibbonImageScale (BOOL bEnable = TRUE)
	{
		m_bIsRibbonImageScale = bEnable;
	}

	BOOL IsRibbonImageScaleEnabled ()
	{
		return m_bIsRibbonImageScale;
	}

	BOOL IsWinXPDrawParentBackground () const
	{
		return m_pfDrawThemeBackground != NULL;
	}

	BOOL DrawParentBackground (CWnd* pWnd, CDC* pDC, LPRECT lpRect = NULL);
	void CleanUp ();

	COLORREF GetColor (int nColor);

	BOOL SetLayeredAttrib (HWND hwnd, COLORREF crKey, BYTE bAlpha, DWORD dwFlags);
	BOOL UpdateLayeredWindow (HWND hwnd, HDC hdcDst, POINT *pptDst, SIZE *psize, HDC hdcSrc,
							POINT *pptSrc, COLORREF crKey, BLENDFUNCTION *pblend, DWORD dwFlags);
	BOOL IsWindowsLayerSupportAvailable () const
	{
		return m_pfSetLayeredWindowAttributes != NULL; 
	}

	BOOL Is32BitIcons () const
	{
		return m_bUseBuiltIn32BitIcons && m_nBitsPerPixel >= 16 && !m_bIsBlackHighContrast && !m_bIsWhiteHighContrast;
	}

	BOOL IsHighContastMode () const
	{
		return m_bIsWhiteHighContrast || m_bIsBlackHighContrast;
	}

	CString RegisterWindowClass (LPCTSTR lpszClassNamePrefix);
	BOOL ExcludeTag (CString& strBuffer, LPCTSTR lpszTag, CString& strTag, BOOL bIsCharsList = FALSE);

	BOOL DwmExtendFrameIntoClientArea (HWND hWnd, MYMARGINS* pMargins);
	LRESULT DwmDefWindowProc (HWND hWnd, UINT message, WPARAM wp, LPARAM lp);
	BOOL DwmIsCompositionEnabled ();

	BOOL DrawTextOnGlass (	HTHEME hTheme, CDC* pDC, int iPartId, int iStateId, 
							CString strText, CRect rect, DWORD dwFlags,
							int nGlowSize = 0, COLORREF clrText = (COLORREF)-1);
	BOOL DrawIconOnGlass (HTHEME hTheme, CDC* pDC, HICON hIcon, CRect rect);

	BOOL GetNonClientMetrics (NONCLIENTMETRICS& ncm);
	UINT GetRebarBandInfoSize ();
	DWORD GetComCtlVersion ();

	BOOL SetDPIAware ();

protected:

	void UpdateTextMetrics ();
	HBITMAP CreateDitherBitmap (HDC hDC);
	
	int	m_nTextHeightHorz;
	int	m_nTextHeightVert;

	int	m_nTextMarginsHorz;
	int	m_nTextMarginsVert;

	int	m_nTextWidthHorz;
	int	m_nTextWidthVert;

	double	m_dblRibbonImageScale;
	BOOL	m_bIsRibbonImageScale;

	HINSTANCE m_hinstUXThemeDLL;
	HINSTANCE m_hinstUser32;
	HINSTANCE m_hinstDwmapiDLL;

	SETLAYEATTRIB m_pfSetLayeredWindowAttributes;
	UPDATELAYEREDWINDOW m_pfUpdateLayeredWindow;

	MY_DRAWTHEMEPARENTBACKGROUND	m_pfDrawThemeBackground;
	MY_DRAWTHEMETEXTEX				m_pfDrawThemeTextEx;
	MY_DRAWTHEMEICON				m_pfDrawThemeIcon;
	MY_BEGINBUFFEREDPAINT			m_pfBeginBufferedPaint;
	MY_BUFFEREDPAINTSETALPHA		m_pfBufferedPaintSetAlpha;
	MY_ENDBUFFEREDPAINT				m_pfEndBufferedPaint;
	MY_DWMEXTENDFRAMEINTOCLIENTAREA	m_pfDwmExtendFrameIntoClientArea;
	MY_DWMDEFWINDOWPROC				m_pfDwmDefWindowProc;
	MY_DWMISCOMPOSITIONENABLED		m_pfDwmIsCompositionEnabled;
	DWORD							m_dwComCtlVersion;
};

extern MYGLOBAL_DATA globalData;

#define IMAGE_MARGIN	4

// MFC Control bar compatibility 
#define CX_BORDER   1
#define CY_BORDER   1

#define CX_GRIPPER  3
#define CY_GRIPPER  3
#define CX_BORDER_GRIPPER 2
#define CY_BORDER_GRIPPER 2


/////////////////////////////////////////////////////////////////////////////

#endif // __GLOBAL_DATA_H
